home *** CD-ROM | disk | FTP | other *** search
-
- #include "BuildControl.h"
-
-
-
- #if defined(qUseDumpFile)
- #include "DumpHeader.h"
- #else
- #include <Memory.h>
- #include <AppleEvents.h>
- #endif
-
-
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
-
- #include "wprintf.h"
-
-
-
- //
- // ------- private stuff -------
- //
-
- #define kWindowAppSig 'MOOS'
- #define kConsoleDisplayClass 'Kons'
- #define kDumpMemoryEvent 'Dmem'
- #define kShowStringEvent 'Sstr'
-
-
- void AESendString (char *str);
- OSErr DBGCreateAETarget (OSType targetSig, AEDesc *targetDesc);
- void GetMemoryDump (Boolean wantDumpHeader,
- Handle *textHandle, Ptr startingAddr,
- long *numberOfBytes);
- long Draw1Space (char *buffer);
- long Draw4CharHex (char *buffer, unsigned short thisWord);
- long DrawAddrLocation (char *buffer, Ptr addrLocation);
- long DrawASCIIDump (char *buffer, Ptr startAddr);
- long Draw16ByteLine (char *buffer, Ptr startAddr);
- long GetDumpHeader (char *buffer, Ptr startingAddr, long numberOfBytes);
-
-
-
-
- //----------------------------------------------------------------------------
- // wprintf
- //
- // str should probably be a global if you're not building standalone code,
- // because sucking up 1K of stack could be bad.
- //----------------------------------------------------------------------------
- #pragma segment AESupport
- void wprintf(const char *format, ...)
- {
- va_list arg;
- long len;
- char str[1024];
-
- va_start(arg, format);
- len = (long) vsprintf(str, format, arg);
- va_end(arg);
-
- if (len > 0)
- AESendString(str);
- }
-
-
- //----------------------------------------------------------------------------
- // wprintmem
- //----------------------------------------------------------------------------
- #pragma segment AESupport
- void wprintmem(Ptr startingAddr, Size numberOfBytes)
- {
- OSErr err;
- AppleEvent theAppleEvent, theReplyEvent;
- AEDesc target;
- long returnedBytes;
- Handle textHandle;
-
- target.dataHandle = NULL;
- theAppleEvent.dataHandle = NULL;
-
- err = DBGCreateAETarget(kWindowAppSig, &target);
-
- if (err == noErr) {
- err = AECreateAppleEvent(kConsoleDisplayClass, kDumpMemoryEvent,
- &target, kAutoGenerateReturnID, kAnyTransactionID,
- &theAppleEvent);
-
- returnedBytes = (long) numberOfBytes;
- GetMemoryDump(true, &textHandle, startingAddr, &returnedBytes);
-
- if (textHandle != NULL) {
- //
- // We have a text handle filled with the memory requested.
- // Put it in the Apple Event as keyDirectObject.
- //
- HLock(textHandle);
- err = AEPutParamPtr(&theAppleEvent, keyDirectObject, typeChar,
- *textHandle, returnedBytes);
- HUnlock(textHandle);
- DisposeHandle(textHandle);
-
- if (err == noErr)
- (void) AESend(&theAppleEvent, &theReplyEvent, kAENoReply,
- kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
- }
- }
-
- //
- // Dispose of everything that was allocated
- //
- if (theAppleEvent.dataHandle != NULL) (void) AEDisposeDesc(&theAppleEvent);
- if (target.dataHandle != NULL) (void) AEDisposeDesc(&target);
-
- }
-
-
- //----------------------------------------------------------------------------
- // DBGCreateAETarget
- //----------------------------------------------------------------------------
- #pragma segment AESupport
- static OSErr DBGCreateAETarget(OSType targetSig, AEDesc *targetDesc)
- {
- return AECreateDesc(typeApplSignature, &targetSig, sizeof(OSType), targetDesc);
- }
-
-
- //----------------------------------------------------------------------------
- // AESendString
- //----------------------------------------------------------------------------
- #pragma segment AESupport
- static void AESendString(char *str)
- {
- OSErr err;
- AppleEvent theAppleEvent, theReplyEvent;
- AEDesc target;
-
- target.dataHandle = NULL;
- theAppleEvent.dataHandle = NULL;
-
- err = DBGCreateAETarget(kWindowAppSig, &target);
-
- if (err == noErr) {
- err = AECreateAppleEvent(kConsoleDisplayClass, kShowStringEvent,
- &target, kAutoGenerateReturnID, kAnyTransactionID,
- &theAppleEvent);
-
- if (err == noErr) {
- err = AEPutParamPtr(&theAppleEvent, keyDirectObject, typeChar,
- str, strlen(str));
-
- if (err == noErr)
- (void) AESend(&theAppleEvent, &theReplyEvent, kAENoReply,
- kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
- }
- }
-
- //
- // Dispose of everything that was allocated
- //
- if (theAppleEvent.dataHandle != NULL) (void) AEDisposeDesc(&theAppleEvent);
- if (target.dataHandle != NULL) (void) AEDisposeDesc(&target);
-
- }
-
-
- //----------------------------------------------------------------------------
- // •• Memory Display code ••
- //----------------------------------------------------------------------------
-
- static char pNumCharTable[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
-
-
- //----------------------------------------------------------------------------
- // FailNULL
- //----------------------------------------------------------------------------
- static void FailNULL(void *addr)
- {
- if (addr == NULL) Debugger();
- }
-
-
- //----------------------------------------------------------------------------
- // Draw1Space
- //
- // Fills buffer with one space at the beginning of buffer
- //
- // RETURNS the number of characters added to buffer (in this case 1)
- //----------------------------------------------------------------------------
- static long Draw1Space(char *buffer)
- {
- FailNULL(buffer);
- buffer[0] = ' ';
- return 1;
- }
-
-
- //----------------------------------------------------------------------------
- // Draw4CharHex
- //
- // Fills buffer with a textual display of the specified word in the form:
- //
- // XXXX
- //
- // at address startAddr.
- //
- // RETURNS the number of characters added to buffer (in this case 4)
- //----------------------------------------------------------------------------
- static long Draw4CharHex(char *buffer, unsigned short thisWord)
- {
- short count;
- unsigned short mask[4] = {0xF000, 0x0F00, 0x00F0, 0x000F};
- unsigned short shift[4] = {12, 8, 4, 0};
- unsigned short tmpShort;
-
- FailNULL(buffer);
-
- for (count = 0; count < 4; count ++) {
- tmpShort = thisWord & mask[count];
- tmpShort >>= shift[count];
- buffer[count] = pNumCharTable[tmpShort];
- }
- return 4;
- }
-
-
- //----------------------------------------------------------------------------
- // DrawAddrLocation
- //
- // Fills buffer with a textual display of the specified address in the form:
- //
- // AAAAAAAA
- //
- // at address startAddr.
- //
- // RETURNS the number of characters added to buffer
- //----------------------------------------------------------------------------
- static long DrawAddrLocation(char *buffer, Ptr addrLocation)
- {
- unsigned long displayLong;
- unsigned short displayWord;
- long bufferPos = 0;
-
- displayLong = (unsigned long)addrLocation;
-
- // Draw the high word of the long
- displayWord = (unsigned short)(displayLong >> 16);
- bufferPos += Draw4CharHex(&buffer[bufferPos], displayWord);
-
- // Draw the low word of the long
- displayWord = (unsigned short)(displayLong & 0xFFFF);
- bufferPos += Draw4CharHex(&buffer[bufferPos], displayWord);
-
- return bufferPos;
- }
-
-
- //----------------------------------------------------------------------------
- // DrawASCIIDump
- //
- // Fills buffer with a display of 16 bytes of memory in ASCII in the form:
- //
- // 'ASCIIASCIIASCIIA'
- //
- // starting at address startAddr. Characters greater than 0xDA and less
- // than 0x20 are shown as '–' instead.
- //
- // RETURNS the number of characters added to buffer
- //----------------------------------------------------------------------------
- static long DrawASCIIDump(char *buffer, Ptr startAddr)
- {
- long bufferPos = 0;
- long counter;
-
- // Put in the single quotes with the memory dump in between
- buffer[bufferPos] = '\'';
- BlockMoveData(startAddr, &buffer[1], 16);
- bufferPos += 17;
- buffer[bufferPos] = '\'';
- bufferPos ++;
-
- // Now scan the line for goofy characters, and replace any of them
- // with a '–' (option-dash).
- for (counter = 0; counter < bufferPos; counter ++) {
- if (((unsigned char)buffer[counter] < 0x20)
- || ((unsigned char)buffer[counter] >= 0xDA))
- buffer[counter] = '–';
- }
-
- return bufferPos;
- }
-
-
- //----------------------------------------------------------------------------
- // Draw16ByteLine
- //
- // Fills buffer with a textual display of 16 bytes of memory in the form:
- //
- // AAAAAAAA NNNN NNNN NNNN NNNN NNNN NNNN NNNN NNNN 'ASCIIASCIIASCIIA'\n
- //
- // starting at address startAddr.
- //
- // RETURNS the number of characters added to buffer
- //----------------------------------------------------------------------------
- static long Draw16ByteLine(char *buffer, Ptr startAddr)
- {
- long bufferPos = 0, incAddress = 0;
- unsigned long displayLong;
- unsigned short displayWord;
- short x, y;
-
- bufferPos += DrawAddrLocation(&buffer[bufferPos], startAddr);
-
- // Put in two spaces;
- bufferPos += Draw1Space(&buffer[bufferPos]);
- bufferPos += Draw1Space(&buffer[bufferPos]);
-
- for ( y = 0; y < 2; y ++) {
- for (x = 0; x < 2; x ++) {
- // Fetch the address to start from
- displayLong = *(unsigned long *)(startAddr + incAddress);
-
- // Draw the high word of the long
- displayWord = (unsigned short)(displayLong >> 16);
- bufferPos += Draw4CharHex(&buffer[bufferPos], displayWord);
-
- // Put in a space
- bufferPos += Draw1Space(&buffer[bufferPos]);
-
- // Draw the low word of the long
- displayWord = (unsigned short)(displayLong & 0xFFFF);
- bufferPos += Draw4CharHex(&buffer[bufferPos], displayWord);
-
- // Put in a space
- bufferPos += Draw1Space(&buffer[bufferPos]);
-
- incAddress += 4;
- }
- // To put in a space after every two longs
- bufferPos += Draw1Space(&buffer[bufferPos]);
- }
-
- // Get the ASCII dump, and the newline at the end.
- bufferPos += DrawASCIIDump(&buffer[bufferPos], startAddr);
- #ifdef __MWERKS__
- buffer[bufferPos] = 13;
- #else
- buffer[bufferPos] = '\n';
- #endif
- bufferPos += 1;
-
- return bufferPos;
-
- }
-
-
- //----------------------------------------------------------------------------
- // GetDumpHeader
- //
- // Fills buffer with text showing information about to be dumped in the form:
- //
- // Dumping DDD bytes starting at location 0xHHHHHHHH:\n\n
- //
- // RETURNS the number of characters added to buffer
- //----------------------------------------------------------------------------
- static long GetDumpHeader( char *buffer,
- Ptr startingAddr,
- long numberOfBytes)
- {
- long bufferPos;
- Str32 tmpBytes;
- Str32 dumpText = "\pDumping ";
- Str32 startingAtLocText = "\p bytes starting at location 0x";
-
- if (buffer == NULL) Debugger();
-
- bufferPos = 0;
-
- // Put in the "Dumping" message
- BlockMoveData(&dumpText[1], &buffer[bufferPos], dumpText[0]);
- bufferPos += dumpText[0];
-
- // Put in the number of bytes to be dumped
- NumToString((long)numberOfBytes, tmpBytes);
- BlockMoveData(&tmpBytes[1], &buffer[bufferPos], tmpBytes[0]);
- bufferPos += tmpBytes[0];
-
- // Put in the second message
- BlockMoveData(&startingAtLocText[1], &buffer[bufferPos], startingAtLocText[0]);
- bufferPos += startingAtLocText[0];
-
- // Put in the starting addr location
- bufferPos += DrawAddrLocation(&buffer[bufferPos], startingAddr);
-
- // Put in the two newlines
- buffer[bufferPos] = '\n';
- bufferPos += 1;
-
- buffer[bufferPos] = '\n';
- bufferPos += 1;
-
- // return the number of bytes filled
- return bufferPos;
- }
-
-
- //----------------------------------------------------------------------------
- // GetMemoryDump
- //
- // Allocates a Handle for a text dump of memory at location startingAddr,
- // and a size of numberOfBytes.
- //
- // INPUT:
- // textHandle
- // pointer to a Handle that will be allocated by the
- // routine, which will contain text dump if successful,
- // or NULL if not.
- //
- // startingAddr
- // address of the first byte to be dumped.
- //
- // numberOfBytes
- // on entry, the number of bytes to be dumped. On exit,
- // this contains the actual size of the dumped memory.
- // numberOfBytes will be rounded up to the amount of
- // memory needed to display the nearest multiple of 16
- // bytes, since that's the amount of memory. Example:
- // -> numberOfBytes = 1
- // <- numberOfBytes = 71, since it takes 71 bytes to
- // display a line of memory.
- //----------------------------------------------------------------------------
- static void GetMemoryDump( Boolean wantDumpHeader,
- Handle *textHandle,
- Ptr startingAddr,
- long *numberOfBytes)
- {
- long lineSize;
- Handle theText;
- char buffer[71];
- long textLen = 0;
- short count;
- short timesThroughLoop;
-
- timesThroughLoop = (*numberOfBytes / 16) + 1;
- theText = NewHandle(0);
-
- if (theText != NULL) {
- // Put in the header if they want it
- if (wantDumpHeader == true) {
- lineSize = GetDumpHeader(&buffer[0], startingAddr, *numberOfBytes);
- SetHandleSize(theText, textLen + lineSize);
- BlockMoveData(&buffer[0], &(*theText)[textLen], lineSize);
- textLen += lineSize;
- }
-
- for (count = 0; count < timesThroughLoop; count++) {
- lineSize = Draw16ByteLine(&buffer[0], (Ptr)((16 * count) + startingAddr));
- SetHandleSize(theText, textLen + lineSize);
- BlockMoveData(&buffer[0], &(*theText)[textLen], lineSize);
- textLen += lineSize;
- }
- }
-
- *numberOfBytes = textLen;
- *textHandle = theText;
- }